import type {
  SearchPageSelectors,
  SearchSelectorConfig,
} from '../../module/page_enhancer/appearance/style_enhancement/platforms'
import type { PageType } from '../page_handler/type'
import {
  BodyAttrs,
  getAllHideSelector,
  getCurrentURL,
  logger,
  loggerDeduplicator,
} from '../../types/constants'
import {
  UNDEFINED_PAGE_TYPE,
  UNDEFINED_PAGE_TYPE_TIPS,
} from '../page_handler/type'

/**
 * 页面路由处理器基类
 */
export abstract class PageRoute {
  abstract readonly name: string
  protected cachedUrl: string | null = null
  private readonly MAX_RETRY = 10 // 最大检测次数
  private readonly RETRY_INTERVAL = 200 // 检测间隔(ms)

  /**
   * 结果选择器
   */
  protected resultSelectors(
    options: {
      pageType: PageType
      selectorConfig: SearchPageSelectors
      includeHideElement?: boolean
      supportedPages?: PageType[]
      notSupportedPages?: PageType[]
    },
  ): SearchSelectorConfig {
    const defaultResult = {
      selector: '',
      container: '',
    }
    const { pageType, selectorConfig, includeHideElement = true, supportedPages = [], notSupportedPages = [] } = options
    const { container, item } = selectorConfig[pageType]?.result || {}
    const isUndefined = !item || !container

    if (!supportedPages.includes(pageType) && notSupportedPages?.includes(pageType)) {
      return defaultResult
    }

    if (isUndefined) {
      if (pageType === UNDEFINED_PAGE_TYPE) {
        loggerDeduplicator.warn(UNDEFINED_PAGE_TYPE_TIPS)
      }
      else {
        loggerDeduplicator.warn(`[${this.name}] 未配置搜索结果相关的选择器`)
      }
    }

    return isUndefined
      ? defaultResult
      : {
          selector: `${item}${includeHideElement ? '' : `:not(${getAllHideSelector()})`}`,
          container,
        }
  }

  /**
   * 获取当前路径
   */
  protected getCurrentUrl(): string {
    // 1. 优先使用内存缓存
    if (this.cachedUrl && this.cachedUrl === getCurrentURL())
      return this.cachedUrl

    // 2. 尝试从 DOM 获取缓存
    const cachedUrl = this.getCachedUrlWithRetry()

    if (cachedUrl) {
      this.cachedUrl = cachedUrl
      return cachedUrl
    }

    // 3. 降级方案
    return getCurrentURL()
  }

  /**
   * 安全获取缓存URL
   */
  private getValidCachedUrl(): string | null {
    const cachedUrl = $(document.body).data(BodyAttrs.FINAL_URL) as string

    if (!cachedUrl)
      return null

    if (this.isValidUrl(cachedUrl)) {
      return cachedUrl
    }

    logger.warn(`[${this.name}] 缓存 URL 格式无效: ${cachedUrl}`)
    return null
  }

  /**
   * URL验证
   */
  private isValidUrl(url: string): boolean {
    // 创建<a>元素验证（无副作用）
    const a = document.createElement('a')
    a.href = url
    return a.host !== '' && a.protocol !== ':'
  }

  /**
   * 带重试的 URL 获取
   */
  private getCachedUrlWithRetry(): string | null {
    let retryCount = 0

    while (retryCount < this.MAX_RETRY) {
      const url = this.getValidCachedUrl()

      if (url && url === getCurrentURL())
        return url

      this.syncWait(this.RETRY_INTERVAL)
      retryCount++
    }

    return null
  }

  /**
   * 同步等待
   */
  private syncWait(ms: number): void {
    const start = Date.now()
    // 添加微任务释放避免完全阻塞
    while (Date.now() - start < ms) {
      if (Date.now() % 10 === 0) {
      // 空循环实现阻塞
      }
    }
  }
}
